#ifndef IMG_VIEWER_H
#define IMG_VIEWER_H

#include <QObject>

#include "img_file.h"
#include "img_widget.h"
#include "img_3dinfection.h"

#include <vtkAxesActor.h>
#include <vtkImageActor.h>
#include <vtkRenderWindow.h>

class vtkCallback;

class img_Viewer: public QObject
{

    Q_OBJECT

private:
    img_Widget * m_axialWidget{nullptr};
    img_Widget * m_coronalWidget{nullptr};
    img_Widget * m_sagittalWidget{nullptr};
    vtkRenderWindow * m_3DSlice{nullptr};
    img_3DInfection * m_3DInfection{nullptr};
    vtkSmartPointer<vtkRenderer> m_render;
    vtkSmartPointer<vtkCallback> m_callback;
    vtkSmartPointer<vtkAxesActor> m_axes;

    img_File * m_img{nullptr};

public:
    img_Viewer(vtkRenderWindow * _axial,
               vtkRenderWindow * _coronal,
               vtkRenderWindow * _sagittal,
               vtkRenderWindow * _3DSlice,
               vtkRenderWindow * _3DInfection,
               QObject* parent = nullptr);
    ~img_Viewer();
    void setImg(img_File * img);
    void setAnalysisImg(vtkImageData * img);
    void unSetAnalysisImg();
    void set3DInfection(vtkImageData * img);
    void unSet3DInfection();
    void setPositionX(int _x);
    void setPositionY(int _y);
    void setPositionZ(int _z);
    void setWindowLevel(double _window, double _level);
    void setCrossLineMode(bool mode);
    void setAxesOpen(bool mode);
    void setAnlsImgOpacity(int _value);

    void reset3D();

private:
    void init3DWidget();
    void initCallback();
    void initConnect();

public:
    void getCurrentPosition(int position[3]);
    short getCurrentPix();
    vtkCallback* getCallBack();
    img_Widget* getAxilaWidget();
    img_Widget* getCoronalWidget();
    img_Widget* getSagittalWidget();
};

class vtkCallback: public QObject, public vtkCommand
{
    Q_OBJECT
public:
    img_Widget *widget[3] {nullptr, nullptr, nullptr};

    static vtkCallback* New()
    {
        return new vtkCallback();
    }

    virtual void Execute(vtkObject *caller, unsigned long ev, void* data)override
    {
        if(false == widget[0]->isOpen()) {
            return;
        }
        if(ev == vtkResliceImageViewer::SliceChangedEvent) {
            vtkResliceImageViewer * riv = dynamic_cast<vtkResliceImageViewer*>(caller);
            if(riv) {//筛选出发信者，并对其进行处理
                if(widget[0]->getImageViewer() == riv) {
                    widget[0]->getAnalysisViewer()->SetSlice(riv->GetSlice());
                    widget[0]->getImagePlaneWidget()->SetSliceIndex(riv->GetSlice());
                    emit widget[0]->sliceChange(riv->GetSlice());
                    syncCrossLine(widget[0], widget[1]);
                    syncCrossLine(widget[0], widget[2]);
                } else if(widget[1]->getImageViewer() == riv) {
                    widget[1]->getAnalysisViewer()->SetSlice(riv->GetSlice());
                    widget[1]->getImagePlaneWidget()->SetSliceIndex(riv->GetSlice());
                    emit widget[1]->sliceChange(riv->GetSlice());
                    syncCrossLine(widget[1], widget[0]);
                    syncCrossLine(widget[1], widget[2]);
                } else if(widget[2]->getImageViewer() == riv) {
                    widget[2]->getAnalysisViewer()->SetSlice(riv->GetSlice());
                    widget[2]->getImagePlaneWidget()->SetSliceIndex(riv->GetSlice());
                    emit widget[2]->sliceChange(riv->GetSlice());
                    syncCrossLine(widget[2], widget[0]);
                    syncCrossLine(widget[2], widget[1]);
                }
            }
        }
        if(ev == vtkCommand::WindowLevelEvent) {
            vtkInteractorObserver * io = dynamic_cast<vtkInteractorObserver*>(caller);
            if(io) {
                double wl[2] {0.0, 0.0};
                if(widget[0]->getDefaultStyle() == io) {
                    widget[0]->getWindowLevel(wl);
                    widget[0]->getImagePlaneWidget()->SetWindowLevel(wl[0], wl[1]);
                    widget[1]->setWindowLevel(wl[0], wl[1]);
                    widget[2]->setWindowLevel(wl[0], wl[1]);
                } else if(widget[1]->getDefaultStyle() == io) {
                    widget[1]->getWindowLevel(wl);
                    widget[1]->getImagePlaneWidget()->SetWindowLevel(wl[0], wl[1]);
                    widget[2]->setWindowLevel(wl[0], wl[1]);
                    widget[0]->setWindowLevel(wl[0], wl[1]);
                } else if(widget[2]->getDefaultStyle() == io) {
                    widget[2]->getWindowLevel(wl);
                    widget[2]->getImagePlaneWidget()->SetWindowLevel(wl[0], wl[1]);
                    widget[0]->setWindowLevel(wl[0], wl[1]);
                    widget[1]->setWindowLevel(wl[0], wl[1]);
                }
                emit windowLevelChange(wl[0], wl[1]);
            }
        }
    }

private:
    void syncCrossLine(img_Widget * from, img_Widget * to)
    {
        double center[3] {0.0, 0.0, 0.0};
        to->getCrossLine()->getCenter(center);
        center[from->getType()] = from->getImageViewer()->GetSlice() *
                                  from->getImgInfo()->pixdim[from->getType() + 1];
        to->getCrossLine()->setCenter(center);
        to->getImageViewer()->Render();
    }

signals:
    void windowLevelChange(double _window, double _level);
};

#endif // IMG_VIEWER_H
